package risoe.syslab.fhnew.controller;

/*
 * Copyright (c) 2012-2014, Technical University of Denmark (DTU)
 * All rights reserved.
 * 
 * The Flexhouse 2.0 platform ("this software") is licensed under the
 * BSD 3-clause license.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   - Neither the name of DTU nor the names of its contributors may be used to
 *     endorse or promote products derived from this software without specific
 *     prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE TECHNICAL UNIVERSITY OF DENMARK BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

import java.rmi.Remote;
import java.rmi.RemoteException;


import risoe.syslab.fhnew.config.BuildingConfig;
import risoe.syslab.fhnew.gui.VisualizationUpdate;
import risoe.syslab.fhnew.hw.Actuator;
import risoe.syslab.model.CompositeMeasurement;

/**
 * The remote interface for communicating with the ControllerManager. Contains methods to:
 * - register new plugincontrollers (with controlled devicetypes and subscriptions)
 * - doing writes to the processimage from plugincontrollers
 * - retrieving the buildingconfig from the controllermanager
 * @author M. Svendsen
 */
public interface ControllerManagerRemoteInterface extends Remote {

	/**
	 * Register a plugincontroller with the given name
	 * @param name the name used to instantiate the plugincontroller
	 * @throws RemoteException is thrown if no controllermanager is running
	 * @throws InstantiationException is thrown if another plugincontroller has already been granted control of one of the devicetypes,
	 * or if a plugincontroller bearing the same name already exists
	 */
	public void registerPluginController(String name) throws RemoteException, InstantiationException;

	/**
	 * Changes the state of an actuator in the processimage if the controller issuing this command has 
	 * sufficient permissions
	 * @param controllerName the name of the controller that issued this command
	 * @param actuatorName the actuator whose state needs changing
	 * @param value the new value for this actuator
	 * @throws RemoteException is thrown if no controllermanager is running
	 * @throws IllegalArgumentException is thrown if the supplied arguments are invalid, or if a PluginController attempts
	 * to do apply an actuation without having acquired the rights to do so.
	 */
	public void setActuator(String controllerName, String actuatorName, CompositeMeasurement value) throws RemoteException, IllegalArgumentException;
	
	/**
	 * Logs a message on the LoggerManager.
	 * @param source
	 * @param type
	 * @param message
	 */
	public void log(String source, String type, String message) throws RemoteException;
	
	/**
	 * @return a BuildingConfig representing the data stored by the ControllerManager
	 * @throws RemoteException is thrown if no ControllerManager is running
	 */
	public BuildingConfig getBuildingConfig() throws RemoteException;
	
	/**
	 * @return an array of actuators. This method is used for delivering data regarding the initial
	 * state of all actuators in the flexhouse. The controller can then decide if the data should be
	 * logged, reacted upon etc.
	 * @throws RemoteException is thrown if no ControllerManager is running
	 */
	public Actuator[] getActuatorStates() throws RemoteException;
	
	/**
	 * Query the value of a sensor by name
	 * @param name of the sensor to query
	 * @return a CompositeMeasurement signifying the current value or null if no sensor has the given name
	 * @throws RemoteException is thrown if no ControllerManager is running
	 */
	public CompositeMeasurement getSensorValue(String name) throws RemoteException;

	/**
	 * Query the value of an actuator by name
	 * @param name of the actuator to query
	 * @return a CompositeMeasurement signifying the current value or null if no actuator has the given name
	 * @throws RemoteException is thrown if no ControllerManager is running
	 */
	public CompositeMeasurement getActuatorValue(String name) throws RemoteException;
	
	/**
	 * Query the setpoint of an actuator by name
	 * @param name of the actuator to query
	 * @return a CompositeMeasurement signifying the current setpoint or null if no actuator has the given name
	 * @throws RemoteException is thrown if no ControllerManager is running
	 */
	public CompositeMeasurement getActuatorSetpoint(String name) throws RemoteException;
	
	/**
	 * Sends a VisualizationUpdate to the UI Manager using RMI
	 * @param update the VisualizationUpdate to send
	 * @throws RemoteException is thrown if no ControllerManager is running
	 */
	public void executeVisualizationUpdate(VisualizationUpdate update) throws RemoteException;
}
